<?php
declare (strict_types = 1);
namespace app\common\model\content;

use app\admin\traits\GetTableData;
use app\common\utils\facade\FileUtil;
use think\db\exception\ModelNotFoundException;
use think\Exception;
use think\Model;
use app\common\model\user\User;

/**
 * @mixin think\Model
 */
class Topic extends Model
{
    use GetTableData;

    const DONE_LIMIT = 5; //话题完结必须满足拥有5篇发布文章

    const DONE_NO = 0; //连载
    const DONE_YES= 1; //完结

    //图片上传字段与目录
    const UP_FIELD = 'topic_cover';
    const UP_FOLDER = 'topic';


    // 设置字段信息
    protected $schema = [
        'id'            => 'int',
        'name'          => 'string',
        'desc'          => 'string',
        'image'         => 'string',
        'count'         => 'int',
        'status'        => 'int',
        'user_id'       => 'int',
        'category_id'   => 'int',
        'create_time'   => 'int',
        'update_time'   => 'int',
    ];

    // 设置字段信息
    protected $type = [
        'id'            => 'integer',
        'count'         => 'integer',
        'status'        => 'integer',
        'user_id'       => 'integer',
        'category_id'   => 'integer',
    ];


    //插入之前完善数据
    public static function onBeforeInsert(Model $model)
    {
        $model->setAttr('user_id',app()->user->getId());
    }

    //关联分类
    public function category()
    {
        return $this->belongsTo(Category::class, 'category_id', 'id')->bind([
            'category_name' => 'name'
        ]);
    }
    //关联文章
    public function articles()
    {
        return $this->hasMany(Article::class,'topic_id', 'id');
    }
    //关联用户
    public function user()
    {
        return $this->belongsTo(User::class,'user_id', 'id')->bind([
            'username' => 'showName',
            'avatar' => 'avatarUrl'
        ]);
    }


    //封面获取器(页面显示图片)
    public function getImageUrlAttr()
    {
        return empty($this->getAttr('image')) ? config('app.empty_image') : showImg($this->getAttr('image'));
    }

    //删除话题之前把话题下的文章置为普通文章(topic_id = 0)
    public static function onBeforeDelete(Model $model)
    {
        return Article::update(['topic_id'=>0],['topic_id' =>  $model->id]) !== false;
    }


    //保存之前转移图片到永久地址
    public static function onBeforeWrite(Model $model){
        //修改话题(如果修改了图片 就先删除原有图片
        //删除图片
        if ($model->isExists() && array_key_exists('image', $model->getChangedData())){
            $real_file = static::getRealPath($model->getOrigin('image'));
            if(is_file($real_file)) FileUtil::unlinkFile($real_file);
        }
        //移动到永久目录
        if(!empty($model->image) && ( !$model->isExists() || array_key_exists('image', $model->getChangedData()))){
            $ori_img = static::getTmpPath($model->image);
            $des_img = static::getRealPath($model->image);

            if(is_file($ori_img)){
                if ( !FileUtil::moveFile($ori_img, $des_img) )
                    return false;
            }
        }

        return true;
    }

    public static function onAfterDelete(Model $model)
    {
        //删除图片
        if(!empty($model->image)) FileUtil::unlinkFile(static::getRealPath($model->image));

    }

    //获取临时文件的绝对路径
    private static function getTmpPath($file){
        return config('filesystem.disks.local.root') . '/'. $file;
    }
    //获取永久文件的绝对路径
    private static function getRealPath($file){
        return config('filesystem.disks.public.root') .'/'. $file;
    }

    /**
     * 获取数据列表
     * @param array $ruleWhere
     * @return array
     * @throws Exception
     */
    public static function getListData(array $ruleWhere = []){
        //要查询的字段
        $fields = [
            'fields' =>['id','name','image','desc','status','count','category_id','user_id','create_time','update_time'],
            'with' => ['category','user'],
            'withCount' => ['articles'],
        ];

        //(构建查询条件)
        $where = [];
        if ($start =input('start_time/s')){
            $where[] = ['create_time', '>=', strtotime($start)];
        }
        if ($end = input('end_time/s')){
            $where[] = ['create_time', '<=', strtotime($end)];
        }
        if ($name = input('name/s')){
            $where[] = ['name','like','%'.$name.'%'];
        }
        if ($cat = input('category_id/d')){
            $where[] = ['category_id','=',$cat];
        }

        //排序
        $order = ['id'=>'desc','create_time'=>'desc'];

        //[count:查询到的数目, list:记录列表]
        return static::operateDatum($where, $fields, $order,$ruleWhere);
    }


    //判断是否允许设置为完结(包含文章数最少5条,不包含草稿,不包含回收站)
    public function allowDone(){
        //判断是否拥有回收站和草稿文章
        if (Article::hasTraOrDra($this->id)) throw new Exception('包含未发布的文章');

        //判断发布的文章是否
        if (Article::counterByTopic($this->id) < static::DONE_LIMIT) throw new Exception('话题至少包含'.static::DONE_LIMIT.'篇文章.');

        //如果没有包含未发布文章并且包含5条以上文航就允许完结
        return true;
    }

    //判断某个话题是否是完结状态
    public static function isDone($id){

        $model = static::find((int) $id);
        if (!$model)
            throw new ModelNotFoundException('数据不存在.');

        return $model->status == static::DONE_YES;
    }



}
